﻿using System.ComponentModel.DataAnnotations.Schema;
using Core.Domain.Contracts;
using Core.Domain.Events;

namespace Core.Domain.Entities;

/// <summary>
/// 组织机构表
/// </summary>
[Table("Organizations")]
public class Organization : AuditableEntity, IAggregateRoot
{
    public string? Name { get; private set; }
    public string? Code { get; private set; }
    public Guid? ParentId { get; private set; }
    // 导航属性
    public virtual Organization? Parent { get; private set; }

    private readonly List<UserOrganization> _userOrganizations = new();
    public virtual IReadOnlyCollection<UserOrganization>? UserOrganizations => _userOrganizations?.AsReadOnly();

    // 私有构造函数，强制通过工厂方法创建
    private Organization() {
    }

    public Organization(string name, string code, Guid? parentId)
    {
        Name = name;
        Code = code;
        ParentId = parentId;
        QueueDomainEvent(new OrganizationCreated(name, code, parentId));
    }

    // 工厂方法：创建组织单元
    public static Organization Create(string name, string code, Guid? parentId)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("组织名称不能为空", nameof(name));

        return new Organization(name, code, parentId);
    }

    // 领域行为：重命名
    public void Rename(string newName)
    {
        if (string.IsNullOrWhiteSpace(newName))
            throw new ArgumentException("新名称不能为空");

        Name = newName.Trim();
    }

    // 领域行为：变更父级
    public void ChangeParent(Guid? newParentId)
    {
        if (newParentId == Id)
            throw new InvalidOperationException("不能将组织设为自己的父级");

        ParentId = newParentId;
    }

    /// <summary>
    /// 领域行为：更新组织编码
    /// </summary>
    public void UpdateCode(string? newCode)
    {
        var oldCode = Code;
        Code = newCode;

        if (oldCode != Code)
        {
            QueueDomainEvent(new OrganizationCodeUpdatedEvent(Id, Code));
        }
    }
}
